package AlgoritmosGeneticos.model.impl.corte;

import AlgoritmosGeneticos.model.CondicionCorte;
import AlgoritmosGeneticos.model.Individuo;
import AlgoritmosGeneticos.model.Poblacion;

public class CorteContenido implements CondicionCorte{

	private int iteracion;
	private int maxIteraciones;
	private int cantidadIteraciones;
	private double porcentaje;
	private Individuo destacadoAnterior; 
	
	/**
	 * CORTE POR CONTENIDO
	 * -------------------
	 * Se cumple mientras se haya obtenido un incremento 
	 * mayor o igual a un porcentaje dado en una cantidad 
	 * de iteraciones. 
	 * 
	 * Este incremento esta dado por la comparacion de los 
	 * ultimos dos valores mas aptos de la poblacion registrados 
	 * en una cantidad de iteraciones dada, mientras la diferencia entre 
	 * ambos valores sea >= a un porcentaje del ultimo primer apto obtenido
	 * la condicion se cumple.
	 * 
	 * @param cantidadIteraciones iteraciones en las que se espera una mejora
	 * @param porcentaje	mejora esperada
	 */
	public CorteContenido(int cantidadIteraciones, double porcentaje) {
		System.out.println("Corte por contenido");
		this.cantidadIteraciones=cantidadIteraciones;
		this.porcentaje=porcentaje;
	}
	
	
	@Override
	public boolean seCumple(Poblacion pob) {
		
		if(this.iteracion % cantidadIteraciones == 0){
			Individuo destacadoActual=pob.getIndividuos().get(0);
			for(Individuo i: pob.getIndividuos()){
				if(i.compareTo(destacadoActual) > 0)
					destacadoActual=i;
			}
			if(destacadoAnterior==null){
				destacadoAnterior=destacadoActual;
			}else{
				double anterior=destacadoAnterior.toNumber();
				double actual=destacadoActual.toNumber();
				// Corto las iteraciones si no se cumple con el incremento esperado
				if(anterior*this.porcentaje <= Math.abs(actual-anterior) ||
						iteracion > maxIteraciones)
					return false;
			}
		}
		this.iteracion++;

		return true;
	}


	@Override
	public void setMaxIterations(int iterations) {
		this.maxIteraciones=iterations;
	}

}
